﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI.Design;
using System.Windows.Forms;
using DriveBeamEditor.Controls.BeamNG.Controls;
using DriveBeamEditor.Controls.BeamNG.Forms;
using JBeamLibrary;
using JBeamLibrary.VehicleParts;

namespace DriveBeamEditor.Controls.BeamNG
{
    public partial class VehicleHierarchyControl : VehicleControl
    {
        #region Fields

        public event EventHandler SelectedVehicleFileChanged;
        public event EventHandler SelectedVehiclePartChanged;
        public event EventHandler<VehiclePart> VehiclePartValidated;

        #endregion

        #region Properties

        /// <summary>Gets the currently selected vehicle file</summary>
        public VehicleFile SelectedVehicleFile
        {
            get { return bsVehicleFiles.Current as VehicleFile; }
        }

        /// <summary>Gets the currently selection vehicle part</summary>
        public VehiclePart SelectedVehiclePart
        {
            get { return bsVehicleParts.Current as VehiclePart; }
            set
            {
                dgvVehicleParts.ClearSelection();
                if (value == null || DesignMode) return;

                var index = bsVehicleParts.IndexOf(value);
                if (bsVehicleParts.Count <= index) return;

                dgvVehicleParts.Rows[index].Selected = true;
            }
        }

        #endregion

        #region CTORs

        public VehicleHierarchyControl()
        {
            InitializeComponent();
        }

        #endregion

        #region Events

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (DesignMode) return;

            bsVehicleFiles.AllowNew = true;
            bsVehicleParts.AllowNew = true;
        }

        private void bsVehicleFiles_CurrentChanged(object sender, EventArgs e)
        {
            BindVehicleParts();

            /* Notify */
            if (SelectedVehicleFileChanged != null)
                SelectedVehicleFileChanged(this, new EventArgs());
        }

        private void bsVehicleParts_CurrentChanged(object sender, EventArgs e)
        {
            /* Notify */
            if (SelectedVehiclePartChanged != null)
                SelectedVehiclePartChanged(this, new EventArgs());
        }

        private void bsVehicleFiles_AddingNew(object sender, AddingNewEventArgs e)
        {
            /* Avoid loop */
            if (e.NewObject is VehicleFile || Vehicle == null) return;

            /* Ask for a name */
            var name = @"unnamed";
            using (var input = TextInputForm.GetNew(@"Enter a vehicle file name", @"File name", true, "", @"Please provide a file name"))
            {
                if (input.ShowDialog(this) == DialogResult.OK)
                    name = input.InputText;
            }

            /* Open new vehicle file dialog */
            e.NewObject = new VehicleFile(name, Vehicle);
        }

        private void bsVehicleParts_AddingNew(object sender, AddingNewEventArgs e)
        {
            /* Avoid loop */
            if (e.NewObject is VehiclePart || Vehicle == null) return;

            /* Ask for a name */
            var name = @"unnamed";
            using (var input = TextInputForm.GetNew(@"Enter a vehicle part name", @"Part name", true, "", @"Please provide a part name"))
            {
                if (input.ShowDialog(this) == DialogResult.OK)
                    name = input.InputText;
            }

            /* Open new vehicle part dialog */
            e.NewObject = new VehiclePart(name, SelectedVehicleFile);
        }

        private void dgvVehicleParts_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (VehiclePartValidated != null)
                VehiclePartValidated(this, SelectedVehiclePart);
        }

        private void dgvVehicleFiles_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            var col = dgvVehicleFiles.Columns[e.ColumnIndex];
            var row = dgvVehicleFiles.Rows[e.RowIndex];

            /* Delete fiel */
            if (col == columnDeleteFile && !row.IsNewRow)
            {
                dgvVehicleFiles.Rows.RemoveAt(e.RowIndex);
            }

            /* Validate new file */
            else if ((col == columnDeleteFile || col == columnSaveFile) && row.IsNewRow)
            {
                bsVehicleFiles.EndEdit();
                dgvVehicleFiles.NotifyCurrentCellDirty(true);
                dgvVehicleFiles.EndEdit();
                dgvVehicleFiles.NotifyCurrentCellDirty(false);
            }

            /* Save file */
            else if (col == columnSaveFile && !row.IsNewRow && SelectedVehicleFile != null)
            {
                SelectedVehicleFile.Save();
            }
        }

        private void dgvVehicleParts_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            /* Get column & row & cell */
            var col = dgvVehicleParts.Columns[e.ColumnIndex];
            var row = dgvVehicleParts.Rows[e.RowIndex];

            /* Validate new row */
            if (row.IsNewRow && col == columnDeletePart)
            {
                bsVehicleParts.EndEdit();
                dgvVehicleParts.NotifyCurrentCellDirty(true);
                dgvVehicleParts.EndEdit();
                dgvVehicleParts.NotifyCurrentCellDirty(false);
            }

            /* Open part */
            else if (col == columnOpenPart)
            {
                if (VehiclePartValidated != null)
                    VehiclePartValidated(this, SelectedVehiclePart);
            }

            /* Delete row */
            else if (col == columnDeletePart)
            {
                dgvVehicleParts.Rows.RemoveAt(e.RowIndex);
            }
        }

        #endregion

        #region Methods

        public override string ToString()
        {
            return "Vehicle structure";
        }

        private void BindVehicleFiles()
        {
            if (Vehicle == null)
            {
                bsVehicleFiles.DataSource = null;
                return;
            }

            bsVehicleFiles.DataSource = Vehicle;
            bsVehicleFiles.AllowNew = true;

            dgvVehicleFiles.Refresh();
            dgvVehicleFiles.Enabled = true;
        }

        private void BindVehicleParts()
        {
            if (SelectedVehicleFile == null)
            {
                bsVehicleParts.DataSource = null;
                return;
            }

            bsVehicleParts.DataSource = SelectedVehicleFile;
            bsVehicleParts.AllowNew = true;

            dgvVehicleParts.Refresh();
            dgvVehicleParts.Enabled = true;
        }

        protected override void OnVehicleChanged()
        {
            /* Update data */
            BindVehicleFiles();
            BindVehicleParts();

            base.OnVehicleChanged();
        }

        public void Reload()
        {
            bsVehicleFiles.ResetBindings(false);
            bsVehicleParts.ResetBindings(false);
        }

        #endregion
    }
}
